﻿using System;
using RayDen.Library.Core.Primitives;
using RayDen.RayEngine.Core.Types;
using RayDen.RayEngine.Data;
using RayDen.RayEngine.Samplers;

namespace RayDen.RayEngine.VertexFramework
{
    public class PathElementFactory
    {
        public static ObserverPathElement ProduceObserver(ref CameraSample cs)
        {
            return new ObserverPathElement()
                {
                    CameraSample = cs,

                };
        }

        public static PathElement ProduceHit(RayEngineScene scene, SurfaceSampler ss, RayBuffer rb, int rayIndex,ref RayData psPathRay, float[] samples)
        {
            //if (ps.PathState == GenericPathSamplerState.Sampling)
            {
                var rayHit = rb.rayHits[rayIndex];

                LightSample ls;

                if (rayHit.Miss())
                {
                    if (scene.EnvironmentMap == null)
                    {
                        return new EnvironmentPathElement()
                            {
                                WOutgoing = -psPathRay.Dir,
                                Throughput = scene.SampleEnvironment(psPathRay.Dir)
                            };
                    }

                    ls = new LightSample()
                    {
                        Spectrum = scene.EnvironmentMap.Le(ref psPathRay.Dir)
                    };
                    return new LightsourcePathElement()
                        {
                            WOutgoing = -psPathRay.Dir,
                            LightSample = ls,
                            Delta = true,
                            Throughput = scene.SampleEnvironment(psPathRay.Dir)
                        };
                }

                var hitPoint = psPathRay.Point(rayHit.Distance);
                var hit = ss.GetIntersection(ref psPathRay, ref rayHit);
                if (hit.IsLight)
                {
                    var lt = scene.GetLightByIndex((int) rayHit.Index);
                    ls = new LightSample()
                        {
                            Spectrum = lt.Le(ref psPathRay.Dir)
                        };
                   
                    return new LightsourcePathElement
                        {
                            LightSample = ls,
                            WOutgoing = -psPathRay.Dir,
                            HitInfo = hit,
                            Delta = false,
                            Throughput = (RgbSpectrum)(lt.Le(ref psPathRay.Dir))
                        };
                }


                return new GeometryPathElement() { HitInfo = hit, HitPoint = hitPoint
                };

            }

             return null;
        }

        public static LightsourcePathElement Produce(SurfaceIntersectionData hit)
        {
            throw new NotImplementedException();
        }

    }
}